Über Atlassian Connect
Um Integrationen für die On-demand-Varianten der Atlassian-Software-Produkte – also Confluence Cloud, Jira Cloud & Co. – zu ermöglichen, steht Entwicklern mit Atlassian Connect ein Framework zur Verfügung, das ihnen dabei hilft, Add-ons in unterschiedlichen Programmiersprachen zu implementieren.
Ein Atlassian-Connect-Add-on ist dabei im Grunde eine Web-Anwendung, die über das HTTP-Protokoll angebunden wird und die folgenden drei Hauptaspekte abdeckt:
- Inhalte in vordefinierte Integrationspunkte in die Benutzeroberfläche des Atlassian-Anwendung integrieren
- Die RESTful Webservices der Atlassian-Anwendung adressieren und verwenden
- Über Webhooks Informationen über Zustandsänderungen in der angebundenen Atlassian-Anwendung erhalten
(Hier finden sich weiterführende Informationen zu Atlassian Connect.)
Im folgenden kurzen Tutorial wollen wir auf diese Aspekte nun näher eingehen.
Was implementieren wir?
Unser Cloud-Plugin integriert sich in Confluence-Cloud-Instanzen, indem es ...
- per Webhook auf das Erstellen neuer Confluence-Seiten lauscht und reagiert.
- sich in das Hilfemenü mit einem Menüpunkt integriert (Teil 2).
- eine Seite in Confluence darstellt, die in unserer Cloud-Anwendung generiert wird (Teil 2).
- per REST-Client OAuth2-authentifizierte Abfragen an ein verbundenes Confluence-Cloud-System durchführt (Teil 2).
Atlassian-Cloud-Entwicklungsumgebung
Atlassian bietet für Entwickler kostenlose Cloud-Instanzen mit den folgenden Benutzer/Agent-Beschränkungen an:
- Jira Core: fünf Benutzer kostenlos
- Jira Software: fünf Benutzer kostenlos
- Confluence: fünf Benutzer kostenlos
- Jira Service Desk: ein Agent kostenlos
Hier gibt es weitere Informationen.
Nach Hause telefonieren mit ngrok
Das Werkzeug ngrok erlaubt es uns, Verbindungen von unserer lokalen Entwicklungsmaschine aus zu tunneln und im Netz bereitzustellen - ideal zum schnellen Testen von Webhooks und Cloud-Plugins.
Von der Website https://ngrok.com/ können wir für alle gängigen Betriebssysteme ein Kommandozeilen-Tool beziehen, um diese Tunnel aufzubauen.
Um beispielsweise eine lokale HTTP-Verbindung auf Port 8080
laufend bereitzustellen, genügt der folgende Befehl:
ngrok http 8080
Dabei erhalten wir eine Zufalls-ID zugewiesen, über die wir nun auf diese Verbindung zugreifen können:
Tunnel Status online Version 2.0.19/prod Web Interface http://127.0.0.1:4040 Forwarding http://12345678.ngrok.io -> localhost:8080 Forwarding https://12345678.ngrok.io -> localhost:8080 Connections ttl opn rt1 rt5 p50 p90 0 0 0.00 0.00 0.00 0.00
Neues Projekt mit Maven-Archetype generieren
Mittels eines Maven-Archetypes kann schnell ein neues Spring-Boot-Projekt samt Atlassian-Bibliotheken generiert werden:
mvn archetype:generate -DarchetypeGroupId=com.atlassian.connect -DarchetypeArtifactId=atlassian-connect-spring-boot-archetype -DarchetypeVersion=1.3.5
Nach Eingabe der GroupID/ArtifactID und Version unserer zu implementierenden Anwendung steht uns ein fertiges Projekt zur weiteren Bearbeitung zur Verfügung:
. |-- pom.xml --- src --- main |-- java | --- net | --- seibertmedia | --- cloud | --- AddonApplication.java --- resources |-- application.yml --- atlassian-connect.json
Neben der klassischen Maven-Projektstruktur erhalten wir ebenfalls:
- Plugin-Descriptor (
atlassian-connect.json
) - Atlassian-Libs:
atlassian-connect-spring-boot-starter
undatlassian-connect-spring-boot-jpa-starter
(inkl. Spring Data JPA und Liquibase-Datenbankmigrationen) - Spring Boot Application-Klasse und Spring-Konfiguration im YAML Format
Anwendung starten
Wir starten unsere Anwendung nun einfach mittels Maven in der Kommandozeile:
mvn spring-boot:run
Im Anschluss können wir unsere Anwendung unter http://localhost:8080
aufrufen; wir werden dann auf den Plugin-Descriptor weitergeleitet.
Anwendung mit ngrok starten
Damit unsere Anwendung nun auch mit entsprechender Basis-URL über den ngrok-Tunnel im Netz laufen kann, ergänzen wir hier einen Startparameter mit der entsprechenden ngrok-URL:
mvn spring-boot:run -Drun.arguments="--addon.base-url=https://12345678.ngrok.io"
Unsere Anwendung sollte nun unter der HTTPS-Variante über ngrok verfügbar sein (https://ID.ngrok.io). HTTPS ist notwendig, da Atlassian zurecht keine Add-ons akzeptiert, die über unverschlüsselte HTTP-only-Verbindungen kommunizieren.
Installation des Confluence-Cloud-Add-ons
Zunächst müssen wir in unserer Confluence-Cloud-Instanz den Entwicklermodus für Add-ons aktivieren, damit wir ohne Marketplace von einer URL den Add-on-Descriptor installieren können.
Dazu gehen wir im Confluence-Administrationsbereich in die Add-on-Verwaltung und setzen unter den Einstellungen das Häkchen für den Entwicklermodus.
Im Anschluss daran können wir unser Add-on über die Angabe unserer ngrok-URL installieren, wie der folgende Screenshot zeigt:
Danach signalisiert eine Erfolgsmeldung die erfolgreiche Integration unseres Add-ons. Diesen Schritt müssen wir künftig nur wiederholen, falls sich unsere URL geändert hat oder wir einen veränderten Plugin-Descriptor (beispielsweise mit Webhooks oder erweiterten Scopes) ausliefern.
Mit Webhooks Systemveränderungen überwachen
Wir wollen nun per Webhook-API benachrichtigt werden, wenn in der Confluence-Cloud-Instanz neue Seiten erstellt werden.
Dazu ergänzen wir zunächst den folgenden Eintrag in unserem Deployment-Descriptor:
"modules": { "webhooks": [ { "event": "page_created", "url": "/pages/created" } ]
Wird in Confluence Cloud eine neue Seite erstellt, ruft Confluence die definierte Adresse auf unserer Cloud-Anwendung auf und liefert Informationen zu diesem System-Event im JSON-Format.
Wir definieren folgendes POJO, in dem wir diese Informationen sammeln wollen:
public class PageCreatedEvent { private Page page; private String user; private String userKey; private String timestamp; private String userName; // getter, setter, toString ommitted }
Wir ergänzen für die Confluence-Seiteninformationen noch ein POJO namens Page
:
public class Page { private String spaceKey; private String modificationDate; private String creatorKey; private String creatorName; private Long id; private String title; private Long version; // getter, setter, tostring ommitted }
Der folgende Endpunkt nimmt nun unter der definierten Adresse die Informationen entgegen und schreibt sie in die Log-Dateien:
@RestController public class WebhookListenerResource { [..] @RequestMapping(name = "/pages/create", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE) public void onPageCreate(@RequestBody PageCreatedEvent dto, @AuthenticationPrincipal AtlassianHostUser hostUser) { log.info("user on host {} with key {} created page: {}", hostUser.getHost().getBaseUrl(), hostUser.getUserKey(), dto); } }
Weiterführende Dokumentationen
Ausblick: Teil 2
Im zweiten Teil werden wir dann die Integration der GUI von Confluence Cloud und die Darstellung Server-seitig gerenderter Inhalte in Confluence implementieren.
Mehr über die Creative-Commons-Lizenz erfahren